home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Games: 500 MB Amiga Software
/
500 MB Amiga Software - Euber 130 - Amiga Games Disc & Mag.iso
/
spiele
/
publicdomain
/
uchess
/
uchesssrc.lha
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-24
|
15KB
|
693 lines
/*#define EIGHT_BIT_SCREEN 1 */
/* main.c - C source for GNU CHESS
*
* Copyright (c) 1988,1989,1990 John Stanback
* Copyright (c) 1992 Free Software Foundation
*
* This file is part of GNU CHESS.
*
* GNU Chess is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GNU Chess is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Chess; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
int CheckIllegal = 0;
extern int IllegalMove;
#include "version.h"
#include "gnuchess.h"
#include <signal.h>
#include <ctype.h>
#ifdef AMIGA
#include <exec/types.h>
#include <exec/exec.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <graphics/gfxbase.h>
#include <proto/intuition.h>
#include <utility/tagitem.h>
#include <graphics/modeid.h>
#include <lhlib.h>
#include <libraries/asl.h>
#include <proto/icon.h>
#include <proto/asl.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
/* Structure for transparent images */
#define PTRHEIGHT 55
#define BLANKDATA 0xffff
int lastpiece=BLANKDATA;
#include "agastuff:amiga.h"
char *ColorStr[2];
char __far *CP[CPSIZE];
/*
* In a networked enviroment gnuchess might be compiled on different hosts
* with different random number generators, that is not acceptable if they
* are going to share the same transposition table.
*/
unsigned int
urand (void)
{
next *= 1103515245;
next += 12345;
return ((unsigned int) (next >> 16) & 0xFFFF);
}
void
srand (unsigned int seed)
{
next = seed;
}
unsigned long hashkey, hashbd;
#ifdef LONGINTS2
struct hashval __far hashcode[2][7][64];
#else
struct hashval hashcode[2][7][64];
#endif
#ifdef CACHE
#ifdef ttblsz
struct hashentry huge *ttable[2];
unsigned int ttblsize;
#endif
#else
#ifdef ttblsz
struct hashentry __far ttable[2][vttblsz + MAXrehash];
unsigned int ttblsize;
#endif
#endif
char savefile[128] = "";
char listfile[128] = "";
#ifdef HISTORY
unsigned char __far history[32768];
#endif
INTSIZE rpthash[2][256];
struct leaf __far Tree[TREE];
struct leaf *root;
INTSIZE TrPnt[MAXDEPTH];
INTSIZE PieceList[2][64], PawnCnt[2][8];
INTSIZE castld[2], Mvboard[64];
INTSIZE svalue[64];
struct flags flag;
INTSIZE opponent, computer, WAwindow, WBwindow, BAwindow, BBwindow, dither, INCscore;
long ResponseTime, ExtraTime, MaxResponseTime, et, et0, time0, ft;
long GenCnt, NodeCnt, ETnodes, EvalNodes, HashCnt, HashAdd, FHashCnt, FHashAdd, HashCol,
THashCol, filesz;
long replus, reminus;
INTSIZE HashDepth = HASHDEPTH, HashMoveLimit = HASHMOVELIMIT;
INTSIZE player, xwndw, rehash;
struct GameRec GameList[MAXMOVES + MAXDEPTH];
INTSIZE Sdepth, GameCnt, Game50, MaxSearchDepth;
INTSIZE epsquare, contempt;
int Book;
struct TimeControlRec TimeControl;
INTSIZE TCflag, TCmoves, TCminutes, TCseconds, OperatorTime;
INTSIZE XCmoves[3], XCminutes[3], XCseconds[3], XC, XCmore;
const INTSIZE otherside[3] =
{black, white, neutral};
unsigned INTSIZE hint;
INTSIZE int TOflag; /* force search re-init if we backup search */
INTSIZE mtl[2], pmtl[2], hung[2];
INTSIZE Pindex[64];
INTSIZE PieceCnt[2];
INTSIZE FROMsquare, TOsquare;
INTSIZE HasKnight[2], HasBishop[2], HasRook[2], HasQueen[2];
INTSIZE ChkFlag[MAXDEPTH], CptrFlag[MAXDEPTH], PawnThreat[MAXDEPTH];
INTSIZE Pscore[MAXDEPTH], Tscore[MAXDEPTH];
const INTSIZE qrook[3] =
{0, 56, 0};
const INTSIZE krook[3] =
{7, 63, 0};
const INTSIZE kingP[3] =
{4, 60, 0};
const INTSIZE rank7[3] =
{6, 1, 0};
const INTSIZE sweep[8] =
{false, false, false, true, true, true, false, false};
unsigned INTSIZE killr0[MAXDEPTH], killr1[MAXDEPTH];
unsigned INTSIZE killr2[MAXDEPTH], killr3[MAXDEPTH];
unsigned INTSIZE PV, SwagHt, Swag0, Swag1, Swag2, Swag3, Swag4, sidebit;
#ifdef KILLT
INTSIZE __far killt[0x4000];
#endif
const INTSIZE value[7] =
{0, valueP, valueN, valueB, valueR, valueQ, valueK};
const INTSIZE control[7] =
{0, ctlP, ctlN, ctlB, ctlR, ctlQ, ctlK};
INTSIZE stage, stage2, Developed[2];
FILE *hashfile;
unsigned int starttime;
INTSIZE int ahead = true, hash = true;
#if defined CHESSTOOL || defined XBOARD
void
TerminateChess (int sig)
{
ExitChess();
}
#endif
int timeopp[MINGAMEIN], timecomp[MINGAMEIN];
int compptr, oppptr;
inline void
TimeCalc ()
{
/* adjust number of moves remaining in gamein games */
int increment = 0;
int topsum = 0;
int tcompsum = 0;
int me,him;
int i;
/* dont do anything til you have enough numbers */
if (GameCnt < (MINGAMEIN * 2)) return;
/* calculate average time in sec for last MINGAMEIN moves */
for (i = 0; i < MINGAMEIN; i++)
{
tcompsum += timecomp[i];
topsum += timeopp[i];
}
topsum /= (100 * MINGAMEIN);
tcompsum /= (100 * MINGAMEIN);
/* if I have less time than opponent add another move */
me = TimeControl.clock[computer]/100;
him = TimeControl.clock[opponent]/100;
if(me < him) increment += 2;
/* if I am losing more time with each move add another */
/*if ( !((me - him) > 60) && tcompsum > topsum) increment++;*/
if ( tcompsum > topsum) increment +=2;
/* but dont let moves go below MINMOVES */
else if (TimeControl.moves[computer] < MINMOVES && !increment) increment++;
/* if I am doing really well use more time per move */
else if (me > him && tcompsum < topsum) increment = -1;
TimeControl.moves[computer] += increment;
}
/* hmm.... shouldn`t main be moved to the interface routines */
int
main (int aargc, char **aargv)
{
char cstring[40];
char *xwin = 0;
char *Lang = NULL;
#ifdef AMIGA
struct WBStartup *startmsg;
struct ExecBase **execbaseptr=(struct ExecBase **)4L;
UWORD cpuid;
struct ExecBase *execbase;
BPTR fp;
APTR tempxx;
struct WBArg *mywbptr;
struct DiskObject *dob;
execbase = *execbaseptr;
cpuid = execbase->AttnFlags;
if (!(cpuid & AFF_68020))
{
exit(0);
}
gfxversion = GfxBase->LibNode.lib_Version;
if (gfxversion < 37)
exit(-1);
if (!aargc)
{
startmsg = (struct WBStartup *)aargv;
mywbptr = startmsg->sm_ArgList;
if (dob = GetDiskObject (mywbptr->wa_Name))
{
xwin = FindToolType(dob->do_ToolTypes,"PRI");
if (xwin)
{
procpri = xwin[0] - '0';
if (procpri < 0)
procpri = 0;
if (procpri > 4)
procpri = 4;
}
xwin = FindToolType(dob->do_ToolTypes,"COLORS");
if (xwin)
{
if ((xwin[0] == '1')&&(xwin[1] == '6'))
gfxversion = 37;
}
xwin = FindToolType(dob->do_ToolTypes,"MONITOR");
if (xwin)
{
if ((xwin[0] == '1')&&(xwin[1] == '5'))
v15Khz = 1;
}
FreeDiskObject (dob);
}
xwin = 0L;
}
else if (aargc > 1)
{
if (!(stricmp(aargv[1],"16")))
{
gfxversion = 37;
}
else if (!(stricmp(aargv[1],"15KHZ")))
{
v15Khz = 1;
}
else
{
procpri=atoi(aargv[1]);
if (procpri < 0)
procpri = 0;
if (procpri > 4)
procpri = 4;
}
}
if (aargc > 2)
{
if (!(stricmp(aargv[2],"16")))
{
gfxversion = 37;
}
else if (!(stricmp(aargv[2],"15KHZ")))
{
v15Khz = 1;
}
else
{
procpri=atoi(aargv[2]);
if (procpri < 0)
procpri = 0;
if (procpri > 4)
procpri = 4;
}
}
if (aargc > 3)
{
if (!(stricmp(aargv[3],"16")))
{
gfxversion = 37;
}
else if (!(stricmp(aargv[3],"15KHZ")))
{
v15Khz = 1;
}
else
{
procpri=atoi(aargv[3]);
if (procpri < 0)
procpri = 0;
if (procpri > 4)
procpri = 4;
}
}
Delay(3L);
myproc = (struct Process *)FindTask(0L);
tempxx = myproc->pr_WindowPtr;
Delay(3L);
myproc->pr_WindowPtr = (APTR)-1L;
if (!(fp = Open("uchess:uchess.lang",MODE_OLDFILE)))
{
system("Assign >nil: uchess: \"\"");
}
else
Close(fp);
myproc->pr_WindowPtr = tempxx;
#endif
srand (starttime = ((unsigned int) time ((long *) 0))); /* init urand */
#ifdef ttblsz
ttblsize = ttblsz;
rehash = -1;
#endif /* ttblsz */
flag.easy = 0;
#ifndef AMIGA
if (argc > 2)
{
if (argv[1][0] == '-' && argv[1][1] == 'L')
{
Lang = argv[2];
argv += 2;
argc -= 2;
}
}
#endif
InitConst (Lang);
ColorStr[0] = CP[118];
ColorStr[1] = CP[119];
#ifndef AMIGA
while (argc > 1 && ((argv[1][0] == '-') || (argv[1][0] == '+')))
{
switch (argv[1][1])
{
case 'a':
ahead = ((argv[1][0] == '-') ? false : true);
break;
case 'h':
hash = ((argv[1][0] == '-') ? false : true);
break;
case 's':
argc--;
argv++;
if (argc > 1)
strcpy (savefile, argv[1]);
break;
case 'l':
argc--;
argv++;
if (argc > 1)
strcpy (listfile, argv[1]);
break;
#if ttblsz
case 'r':
if (argc > 2)
rehash = atoi (argv[2]);
argc--;
argv++;
if (rehash > MAXrehash)
rehash = MAXrehash;
break;
case 'T':
if (argc > 2)
ttblsize = atoi (argv[2]);
argc--;
argv++;
if (ttblsize > 0 && ttblsize < 24)
ttblsize = (1 << ttblsize);
else
ttblsize = ttblsz;
break;
#ifdef HASHFILE
case 't': /* create or test persistent transposition
* table */
hashfile = fopen (HASHFILE, RWA_ACC);
if (hashfile)
{
fseek (hashfile, 0L, SEEK_END);
filesz = (ftell (hashfile) / sizeof (struct fileentry)) - 1;
}
if (hashfile != NULL)
{
long i, j;
int nr[MAXDEPTH];
struct fileentry n;
/*ShowMessage (CP[49]);*/
for (i = 0; i < MAXDEPTH; i++)
nr[i] = 0;
fseek (hashfile, 0L, SEEK_END);
i = ftell (hashfile) / sizeof (struct fileentry);
fseek (hashfile, 0L, SEEK_SET);
for (j = 0; j < i + 1; j++)
{
fread (&n, sizeof (struct fileentry), 1, hashfile);
if (n.depth)
{
nr[n.depth]++;
nr[0]++;
}
}
sprintf (astr,CP[109],
nr[0], i);
/*ShowMessage(astr);*/
for (j = 1; j < MAXDEPTH; j++)
/*
printf ("%d ", nr[j]);
printf ("\n")*/;
}
return 0;
case 'c': /* create or test persistent transposition
* table */
if (argc > 2)
filesz = atoi (argv[2]);
if (filesz > 0 && filesz < 24)
filesz = (1 << filesz) - 1 + MAXrehash;
else
filesz = Deffilesz + MAXrehash;
if ((hashfile = fopen (HASHFILE, RWA_ACC)) == NULL)
hashfile = fopen (HASHFILE, WA_ACC);
if (hashfile != NULL)
{
long j;
struct fileentry n;
/*printf (CP[66]);*/
for (j = 0; j < 32; j++)
n.bd[j] = 0;
n.f = n.t = 0;
n.flags = 0;
n.depth = 0;
n.sh = n.sl = 0;
for (j = 0; j < filesz + 1; j++)
fwrite (&n, sizeof (struct fileentry), 1, hashfile);
fclose (hashfile);
}
/* else
printf (CP[50], HASHFILE);*/
return (0);
#endif /* HASHFILE */
#endif /* ttblsz */
case 'x':
xwin = &argv[1][2];
break;
case 'v':
fprintf (stderr, CP[102], version, patchlevel);
exit (1);
default:
fprintf (stderr, CP[113]);
exit (1);
}
argv++;
argc--;
}
#endif
XC = 0;
MaxResponseTime = 0;
#if defined CHESSTOOL || defined XBOARD
signal (SIGTERM, TerminateChess);
TCflag = true;
TCmoves = 40;
TCminutes = 120;
TCseconds = 0;
TCadd = 0;
OperatorTime = 0;
#else
/* TCflag = false;*/
/* OperatorTime = 0;*/
TCflag = true;
TCmoves = 60;
TCminutes = 10;
TCseconds = 0;
OperatorTime = 0;
#endif
#ifndef AMIGA
if (argc == 2)
{
char *p;
MaxResponseTime = 100L*strtol(argv[1], &p, 10);
if (*p == ':')
MaxResponseTime = 60L*MaxResponseTime +
100L*strtol(++p, (char **) NULL, 10);
TCflag = false;
TCmoves = 0;
TCminutes = 0;
TCseconds = 0;
}
if (argc >= 3)
{
char *p;
if (argc > 9)
{
/* printf ("%s\n", CP[220]);*/
exit (1);
}
TCmoves = atoi (argv[1]);
TCminutes = strtol (argv[2], &p, 10);
if (*p == ':')
TCseconds = strtol (p + 1, (char **) NULL, 10);
else
TCseconds = 0;
TCflag = true;
argc -= 3;
argv += 3;
while (argc > 1)
{
XCmoves[XC] = atoi (argv[0]);
XCminutes[XC] = strtol (argv[1], &p, 10);
if (*p == ':')
XCseconds[XC] = strtol (p + 1, (char **) NULL, 10);
else
XCseconds[XC] = 0;
if (XCmoves[XC] && (XCminutes[XC] || XCseconds[XC]))
XC++;
else
{
/*printf (CP[220]);*/
exit (1);
}
argc -= 2;
argv += 2;
}
if (argc)
{
/*printf ("%s\n", CP[220]);*/
exit (1);
}
}
#endif /* AMIGA */
#ifdef AMIGA
if (!AmigaStartup())
{
exit(2);
}
#endif
Initialize ();
#ifndef CACHE
#ifdef ttblsz
Initialize_ttable ();
#endif /* ttblsz */
#endif
Initialize_dist ();
Initialize_moves ();
FirstTime = 1;
NewGame ();
flag.easy = ahead;
flag.hash = hash;
if (xwin)
xwndw = atoi (xwin);
hashfile = NULL;
#if ttblsz
#ifdef HASHFILE
hashfile = fopen (HASHFILE, RWA_ACC);
if (hashfile)
{
fseek (hashfile, 0L, SEEK_END);
filesz = ftell (hashfile) / sizeof (struct fileentry) - 1;
}
#if !defined CHESSTOOL && !defined XBOARD
else
ShowMessage (CP[98]);
#endif
#endif /* HASHFILE */
#endif /* ttblsz */
#ifdef AMIGA
(void)SetTaskPri((struct Task *)myproc,procpri);
Delay(3L);
SetMenuStrip(wG,&MenuList1); /* attach any Menu */
MenuStripSet = 1;
#endif
while (!(flag.quit))
{
if (flag.bothsides && !flag.mate)
{
SetPointer(wG,myPointer,PTRHEIGHT,0x10L,0L,0L);
SelectMove (opponent, 1);
}
else
{
InputCommand (cstring);
}
if (opponent == black)
if (flag.gamein || TCadd)
{
TimeCalc ();
}
else if (TimeControl.moves[opponent] == 0)
{
if (XC)
if (XCmore < XC)
{
TCmoves = XCmoves[XCmore];
TCminutes = XCminutes[XCmore];
TCseconds = XCseconds[XCmore];
XCmore++;
}
SetTimeControl ();
}
compptr = (compptr + 1) % MINGAMEIN;
if (SupervisorMode)
{
computer = computer ^ 1;
opponent = opponent ^ 1;
xwndw = (computer == white) ? WXWNDW : BXWNDW;
flag.force = false;
Sdepth = 0;
}
else if (!(flag.quit || flag.mate || flag.force))
{
SetPointer(wG,myPointer,PTRHEIGHT,0x10L,0L,0L);
SelectMove (computer, 1);
if (computer == black)
if (flag.gamein)
{
TimeCalc ();
}
else if (TimeControl.moves[computer] == 0)
{
if (XC)
if (XCmore < XC)
{
TCmoves = XCmoves[XCmore];
TCminutes = XCminutes[XCmore];
TCseconds = XCseconds[XCmore];
XCmore++;
}
SetTimeControl ();
}
}
if ((flag.mate)&&(!Mate)&&(!DrawnGame))
ShowMessage("CheckMate");
if (Mate)
{
ShowMessage(MateString);
}
else if (DrawnGame)
{
ShowMessage("Draw..");
}
}
#if ttblsz
#ifdef HASHFILE
if (hashfile)
fclose (hashfile);
#endif /* HASHFILE */
#endif /* ttblsz */
ExitChess ();
}